package ro.romanescu.loc4j.web;

import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.PageContext;
import javax.servlet.jsp.tagext.TagSupport;

import ro.romanescu.loc4j.Dictionary;
import ro.romanescu.loc4j.Localization;


/**
 * JSP tag which makes use of the localization library for web applications.
 */
public class Loc4JTag extends TagSupport {

  /**
   * Name of the variable put on application context for the actual 
   * implementation of Localization interface framework.
   */
  public static String LOC4J_LOCALIZATION = "loc4j.libary";
  
  
  /**
   * Name of the variabile put on application context for the current 
   * application language (ISO code).
   */
  public static String LOC4J_LANGUAGE = "loc4j.language.current";


  /**
   * tag attribute: key
   */
  private String key = "";
  
  
  /**
   * tag attribute: trim
   */
  private boolean trim = false;


  /**
   * Method called at start of tag.
   * @return SKIP_BODY
   */
  public int doStartTag() throws JspException {
    String translatedText = key;
    Object loc4jObject = findAttribute( pageContext, LOC4J_LOCALIZATION );
    if ( loc4jObject != null ) {
      Object currentLanguageObject = findAttribute( pageContext, LOC4J_LANGUAGE );
      if ( currentLanguageObject != null ) {
        Localization loc4j = ( ( Localization )loc4jObject );
        Dictionary dic = loc4j.getDictionary( currentLanguageObject.toString() );
        if( dic != null ) {
          translatedText = dic.getString( key );
        }
      }
    }
    try {
      JspWriter out = pageContext.getOut();
      out.write( trim == false ? translatedText : translatedText.trim() );
    } catch ( Exception e ) {
      e.printStackTrace();
    }
    return SKIP_BODY;
  }


  /**
   * Method is invoked after every body evaluation to control whether 
   * the body will be reevaluated or not.
   * @return SKIP_BODY
   */
  public int doAfterBody() throws JspException {
    return SKIP_BODY;
  }


  /**
   * Method called at end of tag.
   * @return EVAL_PAGE
   */
  public int doEndTag() {
    return EVAL_PAGE;
  }


  /**
   * Setter for key tag attribute.
   * @param key Key attribute for the Dictionary interface
   */
  public void setKey( String key ) {
    this.key = key;
  }


  /**
   * Getter for key tag attribute.
   * @return Key value
   */
  public String getKey() {
    return key;
  }


  private static Object findAttribute( PageContext pageCtx, String attribute ) {
    Object ret = null;
    ret = pageCtx.getSession().getServletContext().getAttribute( attribute );
    if ( ret != null )
      return ret;
    else
      ret = pageCtx.getSession().getAttribute( attribute );
    if ( ret != null )
      return ret;
    else
      ret = pageCtx.getAttribute( attribute );
    return ret;
  }


  /**
   * Setter for trim tag attribute.
   * @param trim Trim the output text
   */
  public void setTrim( boolean trim ) {
    this.trim = trim;
  }


  /**
   * Getter for trim tag attribute. true means to trim the output string.
   * @return trim attribute value
   */
  public boolean isTrim() {
    return trim;
  }
}
